在使用 Git 进行代码管理时,有时候我们在执行 git push
时会遇到如下错误:
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'github.com:xxx/xxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
问题分析
出现这个错误的原因是:远程分支的提交记录比本地分支更新,而 Git 默认不会强制推送导致丢失远程更新的提交。因此,Git 拒绝了此次推送操作。
可能的场景包括:
- 远程仓库有其他人提交了更新,但本地仓库没有同步。
- 本地分支是基于一个过时的远程分支版本创建的。
- 误删了本地的 Git 历史记录,而远程仍然保留旧记录。
解决方案
方法一:执行 git pull --rebase
如果希望保留本地的提交并合并远程最新提交,使用 git pull --rebase
命令:
git pull --rebase origin master
然后重新推送代码:
git push origin master
解释:
git pull --rebase
会先拉取远程仓库最新的代码,并将本地提交的更改重新应用到新的提交上,保持线性历史记录。git push origin master
再次尝试推送更改。
方法二:执行 git pull
并合并
如果不介意合并提交(merge commit),可以使用 git pull
:
git pull origin master
然后解决冲突(如果有),再执行:
git push origin master
解释:
git pull
默认会创建一个合并提交(merge commit),不会修改已有提交历史。- 适用于团队协作但会导致历史记录中额外的合并提交。
方法三:强制推送(谨慎使用)
如果确认本地分支的内容才是正确的,并且可以覆盖远程分支的内容(可能会丢失其他人的提交),可以使用 强制推送:
git push --force origin master
或者更安全的强制推送(避免删除他人新提交):
git push --force-with-lease origin master
⚠️ 注意:
git push --force
会直接覆盖远程分支,可能导致他人提交的代码丢失。git push --force-with-lease
更安全,它会检查远程分支是否已经被其他人修改,避免误覆盖。
预防措施
为了避免 non-fast-forward
错误,可以采取以下措施:
- 定期同步远程分支:在本地开发前,执行
git pull --rebase origin master
以保持最新代码。 - 小步提交并频繁推送:不要长时间本地开发后再一次性推送,减少冲突可能性。
- 使用分支管理:在
master
分支上避免直接提交,建议使用 feature 分支开发,并在合并前确保同步最新代码。
结论
当 git push
被拒绝并提示 non-fast-forward
错误时,可以:
- 使用
git pull --rebase
解决同步问题并保持清晰的提交历史。 - 使用
git pull
进行合并(可能产生 merge commit)。 - 在特殊情况下使用
git push --force
强制推送,但需谨慎操作。
希望这篇文章能帮助你更好地理解和解决 Git 推送被拒绝的问题!